﻿using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;

namespace KeyMaster
{
    public class Program
    {
        // Please change these as you wish!
        static String UncodedMessage = "5"; //"de Key Master version 0.1 by WD4VA k"; // 
        static int Rate = 2 * 60; // I found this to be an acceptable value, but I can't read morse.

        // These you probably don't need to change.
        static OutputPort LED = new OutputPort(Pins.ONBOARD_LED, false);

        static OutputPort Keyer_Port1_Dot = new OutputPort(Pins.GPIO_PIN_D0, false);
        static OutputPort Keyer_Port1_Dash = new OutputPort(Pins.GPIO_PIN_D1, false);
        static OutputPort Keyer_Port2_Dot = new OutputPort(Pins.GPIO_PIN_D2, false);
        static OutputPort Keyer_Port2_Dash = new OutputPort(Pins.GPIO_PIN_D3, false);
        static OutputPort Keyer_Port3_Dot = new OutputPort(Pins.GPIO_PIN_D4, false);
        static OutputPort Keyer_Port3_Dash = new OutputPort(Pins.GPIO_PIN_D5, false);

        static InputPort Reader_Port1_Dot = new InputPort(Pins.GPIO_PIN_D6, true, Port.ResistorMode.Disabled);
        static InputPort Reader_Port1_Dash = new InputPort(Pins.GPIO_PIN_D7, true, Port.ResistorMode.Disabled);
        static InputPort Reader_Port2_Dot = new InputPort(Pins.GPIO_PIN_D8, true, Port.ResistorMode.Disabled);
        static InputPort Reader_Port2_Dash = new InputPort(Pins.GPIO_PIN_D9, true, Port.ResistorMode.Disabled);
        static InputPort Reader_Port3_Dot = new InputPort(Pins.GPIO_PIN_D10, true, Port.ResistorMode.Disabled);
        static InputPort Reader_Port3_Dash = new InputPort(Pins.GPIO_PIN_D11, true, Port.ResistorMode.Disabled);

        static bool Mapping_1_1 = false;
        static bool Mapping_1_2 = true;
        static bool Mapping_1_3 = false;
        static bool Mapping_2_1 = true;
        static bool Mapping_2_2 = true;
        static bool Mapping_2_3 = false;
        static bool Mapping_3_1 = false;
        static bool Mapping_3_2 = false;
        static bool Mapping_3_3 = false;

        static MorseCode Morse;


        /// <summary>
        /// Initialize our attached devices and setup an interrupt.
        /// </summary>
        public static void Main()
        {
            // Set up our interupt port. We're using event based because I think it's badass.
            InterruptPort Toggle = new InterruptPort(Pins.ONBOARD_SW1, false, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeLow);
            Toggle.OnInterrupt += new NativeEventHandler(Toggle_OnInterrupt);


            Morse = new MorseCode(UncodedMessage); // Setting up the MorseCode

            do
            {
                if (Mapping_1_1)
                {
                    Keyer_Port1_Dot.Write(Reader_Port1_Dot.Read());
                    Keyer_Port1_Dash.Write(Reader_Port1_Dash.Read());
                }
                if (Mapping_1_2)
                {
                    Keyer_Port1_Dot.Write(Reader_Port2_Dot.Read());
                    Keyer_Port1_Dash.Write(Reader_Port2_Dash.Read());
                }
                if (Mapping_1_3)
                {
                    Keyer_Port1_Dot.Write(Reader_Port3_Dot.Read());
                    Keyer_Port1_Dash.Write(Reader_Port3_Dash.Read());
                }
                if (Mapping_2_1)
                {
                    Keyer_Port2_Dot.Write(Reader_Port1_Dot.Read());
                    Keyer_Port2_Dash.Write(Reader_Port1_Dash.Read());
                }
                if (Mapping_2_2)
                {
                    Keyer_Port2_Dot.Write(Reader_Port2_Dot.Read());
                    Keyer_Port2_Dash.Write(Reader_Port2_Dash.Read());
                }
                if (Mapping_2_3)
                {
                    Keyer_Port2_Dot.Write(Reader_Port3_Dot.Read());
                    Keyer_Port2_Dash.Write(Reader_Port3_Dash.Read());
                }
                if (Mapping_3_1)
                {
                    Keyer_Port3_Dot.Write(Reader_Port1_Dot.Read());
                    Keyer_Port3_Dash.Write(Reader_Port1_Dash.Read());
                }
                if (Mapping_3_2)
                {
                    Keyer_Port3_Dot.Write(Reader_Port2_Dot.Read());
                    Keyer_Port3_Dash.Write(Reader_Port2_Dash.Read());
                }
                if (Mapping_3_3)
                {
                    Keyer_Port3_Dot.Write(Reader_Port3_Dot.Read());
                    Keyer_Port3_Dash.Write(Reader_Port3_Dash.Read());
                }

                if (Reader_Port1_Dot.Read())
                {
                    Debug.Print("Reader 1: Dot");
                }
                if (Reader_Port1_Dash.Read())
                {
                    Debug.Print("Reader 1: Dash");
                }
                if (Reader_Port2_Dot.Read())
                {
                    Debug.Print("Reader 2: Dot");
                }
                if (Reader_Port2_Dash.Read())
                {
                    Debug.Print("Reader 2: Dash");
                }
                if (Reader_Port3_Dot.Read())
                {
                    Debug.Print("Reader 3: Dot");
                }
                if (Reader_Port3_Dash.Read())
                {
                    Debug.Print("Reader 3: Dash");
                }





                //Thread.Sleep(10); // Wait for interupt.




                /*
                if (Reader_Port1_Dash.Read() == true)
                {
                    Keyer_Port1_Dash.Write(true);
                    SendMorse(Test_Port1_Dash);
                    Thread.Sleep(Rate * 10); // Wait 3 ticks.
                    Keyer_Port1_Dash.Write(false);
                }
            */
            }
            while (true);


            //Thread.Sleep(Timeout.Infinite); // Wait for interupt.
        }

        /// <summary>
        /// Sends the message when button is pressed.
        /// </summary>
        /// <param name="Data1">Unused.</param>
        /// <param name="Data2">Unused.</param>
        /// <param name="Time">Unused.</param>
        public static void Toggle_OnInterrupt(uint Data1, uint Data2, DateTime Time)
        {
            SendMorse(Morse);
            //Mapping_1_1 = !Mapping_1_1;
        }


        /// <summary>
        /// Sends the Morse to the LED and pauses when needed.
        /// </summary>
        private static void SendMorse(MorseCode signal)
        {
            for (int i = 0; i < 5; i++)
            {
                // Run through each relay....
                Keyer_Port1_Dot.Write(true);
                Thread.Sleep(Rate); // Wait 1 ticks!
                Keyer_Port1_Dot.Write(false);
                Keyer_Port1_Dash.Write(true);
                Thread.Sleep(Rate); // Wait 1 ticks!
                Keyer_Port1_Dash.Write(false);

                Keyer_Port2_Dot.Write(true);
                Thread.Sleep(Rate); // Wait 1 ticks!
                Keyer_Port2_Dot.Write(false);
                Keyer_Port2_Dash.Write(true);
                Thread.Sleep(Rate); // Wait 1 ticks!
                Keyer_Port2_Dash.Write(false);

                Keyer_Port3_Dot.Write(true);
                Thread.Sleep(Rate); // Wait 1 ticks!
                Keyer_Port3_Dot.Write(false);
                Keyer_Port3_Dash.Write(true);
                Thread.Sleep(Rate); // Wait 1 ticks!
                Keyer_Port3_Dash.Write(false);
            }


            for (int step = 0; step < signal.SignalCount(); step++)
            {
                switch (signal.GetSignal(step))
                {
                    case 1:
                        Debug.Print("Morse: Dot happening!");
                        LED.Write(true);
                        Thread.Sleep(Rate); // Wait 1 tick!
                        LED.Write(false);
                        Thread.Sleep(Rate); // 1 tick between signals, always!
                        break;
                    case 2:
                        Debug.Print("Morse: Dash Happening!");
                        LED.Write(true);
                        Thread.Sleep(Rate * 3); // Wait 3 ticks.
                        LED.Write(false);
                        Thread.Sleep(Rate); // 1 tick between signals, always!
                        break;
                    case 3:
                        Debug.Print("Morse: Letter Break Happening!");
                        Thread.Sleep(Rate * 2); // We have 1 rate sleep from the last char.
                        break;
                    case 4:
                        Debug.Print("Morse: Word Break Happening!");
                        Thread.Sleep(Rate * 6); // We have 1 rate sleep from the last char.
                        break;
                    default:
                        Debug.Print("Morse: There was an error!");
                        break;
                }
            }
        }
    }
}
